<template>
    <section :class="`onvif ${fullscreen === true ? 'fullscreen' : ''}`" v-loading="loading"
        element-loading-text="视频数据载入中..." element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(255, 255, 255, 0.2)">
        <div class="container theme-showcase" ref="container" role="main">
            <form v-show="!readonly" class="form-horizontal connect-form" ref="connect-form">
                <div class="form-group">
                    <label for="device" class="col-sm-2 control-label">Device</label>
                    <div class="col-sm-10">
                        <select v-if="xaddr === '' || xaddr === null" class="form-control" id="device" name="device">
                            <option>now searching...</option>
                        </select>
                        <input v-else type="text" class="form-control" id="device" name="device"
                            :disabled="xaddr === ''" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="user" class="col-sm-2 control-label">Username</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="user" name="user" :disabled="xaddr === ''" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="pass" class="col-sm-2 control-label">Password</label>
                    <div class="col-sm-10">
                        <input type="password" class="form-control" id="pass" name="pass" :disabled="xaddr === ''" />
                    </div>
                </div>
                <button type="button" class="form-control btn btn-primary" name="connect" :disabled="xaddr === ''">
                    Connect
                </button>
            </form>

            <div class="connected-device" ref="connected-device">
                <p style="pointer-events: none; display: grid;">
                    <video ref="canvas" class="snapshot" muted preload="auto" />
                </p>
                <div ref="device-msg" class="device-msg">
                    设备初始化中...
                </div>
                <div class="device-info-box">
                    <span class="name"></span> (<span class="address"></span>)
                </div>
                <div class="ptz-ctl-box" v-show="loadError === false">
                    <button type="button" class="ptz-goto-home">
                        <span class="glyphicon glyphicon-home" title="回到home点(部分摄像机无效)" style="left: -1px;"></span>
                    </button>
                    <div class="ptz-pad-box">
                        <span class="left glyphicon glyphicon-menu-left" title="向左"></span>
                        <span class="right glyphicon glyphicon-menu-right" title="向右"></span>
                        <span class="up glyphicon glyphicon-menu-up" title="向上"></span>
                        <span class="down glyphicon glyphicon-menu-down" title="向下"></span>
                    </div>
                </div>
                <div class="ptz-spd-ctl-box" v-show="loadError === false">
                    <span class="label">键盘控制PTZ的速度</span>
                    <div class="btn-group btn-group-sm" data-toggle="buttons">
                        <label :class="`btn btn-default ${ptzSpeed == 0.5 ? 'active' : ''}`"><input type="radio"
                                name="ptz-speed" value="0.5" @click="ptzSpeed = 0.5" checked />慢</label>
                        <label :class="`btn btn-default ${ptzSpeed == 0.75 ? 'active' : ''}`"><input type="radio"
                                name="ptz-speed" value="0.75" @click="ptzSpeed = 0.75" />中</label>
                        <label :class="`btn btn-default ${ptzSpeed == 1 ? 'active' : ''}`"><input type="radio"
                                name="ptz-speed" value="1.0" @click="ptzSpeed = 1" />快</label>
                    </div>
                </div>
                <div class="ptz-zom-ctl-box btn-group btn-group-lg" role="group" aria-label="Zoom" v-show="loadError === false">
                    <button type="button" class="ptz-zom ptz-zom-ot btn btn-default">
                        <span class="glyphicon glyphicon-zoom-out"></span>
                    </button>
                    <button type="button" class="ptz-zom ptz-zom-in btn btn-default">
                        <span class="glyphicon glyphicon-zoom-in"></span>
                    </button>
                    <button type="button" class="ptz-zom ptz-video btn btn-default" ref="videoBtn" @click="downVideo">
                        <svg t="1723861235325" class="icon" viewBox="0 0 1024 1024" version="1.1"
                            xmlns="http://www.w3.org/2000/svg" p-id="6980" width="20" height="18"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                            <path
                                d="M682.666667 170.666667a42.666667 42.666667 0 0 1 42.666666 42.666666v179.2l222.421334-155.733333a21.333333 21.333333 0 0 1 33.578666 17.493333v515.413334a21.333333 21.333333 0 0 1-33.578666 17.493333L725.333333 631.466667V810.666667a42.666667 42.666667 0 0 1-42.666666 42.666666H85.333333a42.666667 42.666667 0 0 1-42.666666-42.666666V213.333333a42.666667 42.666667 0 0 1 42.666666-42.666666h597.333334z m-256 170.666666H341.333333v170.666667H213.333333l170.666667 170.666667 170.666667-170.666667h-128V341.333333z"
                                fill="#333333" />
                        </svg>
                    </button>
                    <button type="button" class="ptz-zom ptz-photo btn btn-default" ref="photoBtn" @click="downPhoto">
                        <svg t="1723861819031" class="icon" viewBox="0 0 1024 1024" version="1.1"
                            xmlns="http://www.w3.org/2000/svg" p-id="8322" width="20" height="18"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                            <path
                                d="M860.414581 207.449017 509.333781 207.449017c0-52.808332-43.003528-95.81186-95.81186-95.81186l-63.817235 0c-52.808332 0-95.81186 43.003528-95.81186 95.81186L158.424996 207.449017c-52.808332 0-95.81186 43.003528-95.81186 95.81186l0 510.53788c0 52.808332 43.003528 95.81186 95.81186 95.81186l701.989585 0c52.808332 0 95.81186-43.003528 95.81186-95.81186L956.22644 303.260877C956.054426 250.452545 913.050899 207.449017 860.414581 207.449017zM509.333781 749.981522c-105.616664 0-191.451705-85.835041-191.451705-191.451705s85.835041-191.451705 191.451705-191.451705 191.451705 85.835041 191.451705 191.451705S614.950445 749.981522 509.333781 749.981522zM812.422644 430.895347c-26.490173 0-47.819923-21.501764-47.819923-47.819923s21.501764-47.819923 47.819923-47.819923c26.490173 0 47.819923 21.501764 47.819923 47.819923S838.912817 430.895347 812.422644 430.895347z"
                                fill="#333333" />
                        </svg>
                    </button>
                    <button type="button" class="ptz-zom ptz-photo btn btn-default" ref="photoBtn"
                        @click="goFullScreen">
                        <svg v-if="fullscreen" t="1724076756222" class="icon" viewBox="0 0 1024 1024" version="1.1"
                            xmlns="http://www.w3.org/2000/svg" p-id="2105" width="20" height="18"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                            <path
                                d="M298.666667 631.466667H226.133333v-81.066667h217.6v204.8h-85.333333v-68.266667l-128 128L170.666667 759.466667l128-128z m422.4 0l128 128-59.733334 59.733333-128-128v68.266667h-85.333333V554.666667h217.6v81.066666h-72.533333zM298.666667 341.333333L187.733333 230.4 243.2 170.666667l115.2 115.2V217.6h85.333333v204.8H226.133333V341.333333H298.666667z m430.933333 0h64v81.066667h-217.6V217.6h85.333333v72.533333L780.8 170.666667l59.733333 59.733333L729.6 341.333333z"
                                fill="#333333" p-id="2106"></path>
                        </svg>
                        <svg v-else t="1724076698930" class="icon" viewBox="0 0 1024 1024" version="1.1"
                            xmlns="http://www.w3.org/2000/svg" p-id="1889" width="20" height="18"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                            <path
                                d="M358.4 768H426.666667v85.333333H213.333333v-213.333333h85.333334v68.266667l128-128 59.733333 59.733333-128 128z m345.6 0l-128-128 59.733333-59.733333 132.266667 132.266666V640h85.333333v213.333333h-213.333333v-85.333333h64zM358.4 298.666667l128 128-59.733333 59.733333-128-128V426.666667H213.333333V213.333333h213.333334v85.333334H358.4z m345.6 0H640V213.333333h213.333333v213.333334h-85.333333V354.133333l-132.266667 132.266667-59.733333-59.733333 128-128z"
                                fill="#333333"></path>
                        </svg>
                    </button>
                </div>
                <div class="disconnect-box">
                    <button type="button" class="form-control btn btn-default" name="disconnect">
                        Disconnect
                    </button>
                </div>
            </div>
        </div>

        <div class="modal fade" tabindex="-1" role="dialog" id="message-modal">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                        <h4 class="modal-title"></h4>
                    </div>
                    <div class="modal-body">
                        <p class="modal-message"></p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">
                            Close
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </section>
</template>

<script>
import $, { error } from 'jquery';
import OnvifManager from "./onvif.js";
import mpegts from 'mpegts.js'
import flvjs from 'flv.js'
export default {
    name: "Index",
    components: {},
    props: {
        readonly: {
            type: Boolean,
            default: false,
        },
        xaddr: {
            type: String,
            default: "",
        },
        user: {
            type: String,
            default: "",
        },
        pass: {
            type: String,
            default: "",
        },
        reConnect: {
            type: Boolean,
            default: false,
        },
        _reConnectDelay: {
            type: Number,
            default: 3,
        },
        _height: {
            type: Number,
        },
        _width: {
            type: Number,
        },
        rtsp: {
            type: String,
            default: '',
        }
    },
    emits: ["presets"],
    watch: {
        _reConnectDelay(newValue, oldValue) {
            if (isNaN(newValue)) this.reConnectDelay = 3;
            if (Number(newValue) < 3) this.reConnectDelay = 3;
            if (Number(newValue) > 20) this.reConnectDelay = 20;
            this.reConnectDelay = newValue;
        },
    },
    computed: {},
    data() {
        return {
            flvPlayer: null,
            ptzSpeed: 0.5,
            reConnectDelay: this._reConnectDelay,
            reInterval: null,
            player: null,
            onvif: new OnvifManager,
            fullscreen: false,
            loading: true,
            loadError: false,
        };
    },
    mounted() { },
    unmounted() { },
    created() {
        setTimeout(() => {
            this.init();
        }, 1000);
    },
    // 销毁
    destroy() {
        this.destroy()
    },
    beforeDestroy() {
        this.destroy()
    },
    methods: {
        goFullScreen() {
            this.fullscreen = !this.fullscreen;
            this.$nextTick(() => {
                window.dispatchEvent(new Event("resize"));
            })
        },
        destroy(load) {
            if (load === true) this.loading = load;
            if (this.onvif && this.onvif.destroy) {
                try {
                    this.onvif.destroy();
                } catch (error) { }
            }
            if (!this.flvPlayer) return false;
            this.flvPlayer.pause();
            this.flvPlayer.unload();
            this.flvPlayer.detachMediaElement();
            this.flvPlayer.destroy();
            this.flvPlayer = null;
            console.log("player is destroy");
        },
        init() {
            const container = $(this.$refs.container);
            const frm_desc = container.find('.connect-desc');
            const frm_con = container.find('.connect-form');
            let sel_dev = frm_con.find('[name="device"]');
            // if (sel_dev.length > 0) sel_dev=sel_dev[0];
            let inp_usr = frm_con.find('[name="user"]');
            // if (inp_usr.length > 0) inp_usr=inp_usr[0];
            let inp_pas = frm_con.find('[name="pass"]');
            // if (inp_pas.length > 0) inp_pas=inp_pas[0];
            let btn_con = frm_con.find('[name="connect"]');
            // if (btn_con.length > 0) btn_con=btn_con[0];

            const div_pnl = $(this.$refs['connected-device']);
            let img_snp = div_pnl.find('.snapshot');
            // if (img_snp.length > 0) img_snp=img_snp[0];
            let btn_dcn = div_pnl.find('button[name="disconnect"]');
            // if (btn_dcn.length > 0) btn_dcn=btn_dcn[0];
            let ptz_spd = div_pnl.find('button[name="ptz-speed"]');
            // if (ptz_spd.length > 0) ptz_spd=ptz_spd[0];
            let btn_hme = div_pnl.find('button.ptz-goto-home');
            // if (btn_hme.length > 0) btn_hme=btn_hme[0];
            let ptz_pad = div_pnl.find('div.ptz-pad-box');
            // if (ptz_pad.length > 0) ptz_pad=ptz_pad[0];
            let zom_in = div_pnl.find('div.ptz-zom-ctl-box button.ptz-zom-in');
            // if (zom_in.length > 0) zom_in=zom_in[0];
            let zom_out = div_pnl.find('div.ptz-zom-ctl-box button.ptz-zom-ot');
            // if (zom_out.length > 0) zom_out=zom_out[0];

            let canvas = container.find('.snapshot');
            if (this._width && this._height) {
                canvas.width = this._width;
                canvas.height = this._height;
            }

            const containerObject = {
                container,
                readonly: this.readonly,
                frm_con,
                frm_desc,
                div_pnl,
                sel_dev,
                inp_usr,
                inp_pas,
                btn_con,
                img_snp,
                btn_dcn,
                ptz_spd,
                btn_hme,
                ptz_pad,
                zom_in,
                zom_out,
                canvas,
                height: this._height,
                width: this._width,
            }
            // this.pass = '1111'
            console.log("rtsp===="+this.rtsp);
            this.onvif.init(containerObject, this.xaddr, this.user, this.pass, this.rtsp, (id, res) => {
                if (res.error) {
                    this.loadError = true;
                } else {
                    this.loadError = false;
                }
                this.$forceUpdate();
                if (id == "connect") {
                    let type = 'flv';
                    const videoElement = canvas.get(0)
                    if (type === 'flv') {
                        let rtspUri = res?.result?.rtsp.replace('[local]', `${location.hostname}:${location.port}`);
                        const url = `${rtspUri}`; //`http://localhost:15000/live/d1b6624d20ca33f2a8ea8751a5a07bd5.flv`;
                        if (flvjs.isSupported() && url) {
                            this.flvPlayer = flvjs.createPlayer(
                                {
                                    type: "flv",
                                    url: url,
                                    hasAudio: false,
                                },
                                {
                                    enableWorker: false, //不启用分离线程
                                    enableStashBuffer: false, //关闭IO隐藏缓冲区
                                    reuseRedirectedURL: true, //重用301/302重定向url，用于随后的请求，如查找、重新连接等。
                                    autoCleanupSourceBuffer: true, //自动清除缓存
                                    stashInitialSize: 128, // 减少首帧显示等待时长
                                    deferLoadAfterSourceOpen: false
                                }
                            );

                            this.$refs.canvas.addEventListener('loaded', () => {
                                console.log('视频加载成功');
                            });

                            this.$refs.canvas.addEventListener('playing', () => {
                                console.log('视频开始播放');
                                if (this.loading === true) {
                                    this.loading = false;
                                }
                            });
                            this.flvPlayer.attachMediaElement(this.$refs.canvas);
                            this.flvPlayer.load();

                            // let controller = this.flvPlayer._transmuxer._controller;
                            // controller._remuxer = {
                            //   flushStashedSamples: function () {
                            //     console.log("flushStashedSamples")
                            //   }
                            // };

                            setTimeout(() => {

                                // 加载完成
                                this.flvPlayer.on(flvjs.Events.LOADING_COMPLETE, () => {
                                });

                                // 加载失败
                                this.flvPlayer.on(flvjs.Events.ERROR, () => {
                                    this.error = true;
                                }, (error) => {
                                    console.log(error, '错误');
                                });
                                this.flvPlayer.play && this.flvPlayer.play();
                            }, 10);
                        }
                    }


                    this.$refs['device-msg'].innerHTML = "";
                    setTimeout(() => {
                        if (!(this._width && this._height)) {
                            window.dispatchEvent(new Event("resize"));
                        }
                        this.$emit("connect");
                    }, 500);
                } else if (id == "downPhoto") {
                    this.$refs.photoBtn.disabled = false;
                    this.$refs.videoBtn.disabled = false;
                    // 创建<a>元素
                    const a = document.createElement('a');
                    const { data } = res;
                    a.href = data;
                    a.download = '保存视频画面.jpg';
                    // a.download = 'example.txt'; // 指定下载的文件名
                    // 将<a>元素添加到body中，这样它就可以被点击
                    document.body.appendChild(a);
                    // 触发点击事件以开始下载
                    a.click();
                    // 从body中移除<a>元素
                    document.body.removeChild(a);
                    this.$refs['device-msg'].innerHTML = "截屏图片保存完成";
                    setTimeout(() => {
                        this.$refs['device-msg'].innerHTML = "";
                    }, 3000);
                } else if (id == "downVideo") {
                    this.$refs.photoBtn.disabled = false;
                    this.$refs.videoBtn.disabled = false;
                    // 创建<a>元素
                    const a = document.createElement('a');
                    const { data } = res;
                    a.href = data;
                    a.download = '保存视频.mp4';
                    // a.download = 'example.txt'; // 指定下载的文件名
                    // 将<a>元素添加到body中，这样它就可以被点击
                    document.body.appendChild(a);
                    // 触发点击事件以开始下载
                    a.click();
                    // 从body中移除<a>元素
                    document.body.removeChild(a);
                    this.$refs['device-msg'].innerHTML = "15秒的视频文件保存完成";
                    setTimeout(() => {
                        this.$refs['device-msg'].innerHTML = "";
                    }, 3000);
                } else if (id == "setPreset") {
                    console.log(res);
                    this.$emit("setPresetCallback", res);
                } else if (id == "getPresets") {
                    this.$emit("presets", res.list);
                } else if (id == "close") {
                    if (this.player !== null) {
                        this.flvPlayer.destroy();
                        this.player = null;
                    }
                    if (this.reConnect === true) {
                        res = `after ${this.reConnectDelay} seconds, automatically reconnect`;
                        this.$emit(id, res);
                        if (this.reInterval) clearInterval(this.reInterval);
                        this.reInterval = setTimeout(() => {
                            this.init();
                        }, this.reConnectDelay * 1000);
                    } else {
                        this.$emit(id, res);
                    }
                } else if (id == "error") {
                    this.$emit(id, res);
                }
            });
        },
        setPreset(token, isadd = false) {
            this.onvif.setPreset(token, isadd);
        },
        gotoPreset(token) {
            this.onvif.gotoPreset(token);
        },
        removePreset(token) {
            this.onvif.removePreset(token);
        },
        reboot() {
            this.onvif.reboot();
        },
        setHome() {
            this.onvif.ptzSetHome();
        },
        downVideo() {
            this.$refs.videoBtn.disabled = true;
            this.$refs.photoBtn.disabled = true;
            this.$refs['device-msg'].innerHTML = "开始保存15秒的视频文件...";
            this.onvif.downVideo();
        },
        downPhoto() {
            this.$refs.videoBtn.disabled = true;
            this.$refs.photoBtn.disabled = true;
            this.$refs['device-msg'].innerHTML = "开始截屏并保存图片...";
            this.onvif.downPhoto();
        },
    },
};
</script>

<style scoped lang="scss">
@import "~css/bootstrap.min.css";
@import "~css/bootstrap-theme.min.css";

audio,
canvas,
progress,
video {
    display: inline-block;
    vertical-align: baseline
}

.onvif {
    font-family: YuGothic, "Meiryo", sans-serif, "Hiragino Kaku Gothic Pro";
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.5);
    overflow: hidden;

    &.fullscreen {
        position: absolute;
        z-index: 10000;
        left: 0px;
        right: 0px;
        top: 0px;
        bottom: 0px;
        width: 100%;
        height: 100%;
        max-width: 100%;
        max-height: 100%;

        .container {
            height: 100% !important;
            max-height: 100% !important;

            .connected-device,
            .snapshot {
                height: 100% !important;
                max-height: 100% !important;
                left: 0px !important;
                width: 100% !important;
            }
        }
    }

    .container {
        width: 100%;
        margin: 0px;
        padding: 0px;

        .connected-device {
            position: relative;
            background-color: #000000;
            overflow: hidden;
            display: none;

            .snapshot {
                position: absolute;
            }

            div.ptz-spd-ctl-box {
                position: absolute;
                bottom: 10px;
                left: 1em;
                background-color: rgba(255, 255, 255, 0.5);
                border-radius: 0.3em;

                .btn-default {
                    min-width: 40px;
                }
            }

            div.ptz-spd-ctl-box span.label {
                display: block;
                margin-top: 0.3em;
            }

            div.device-info-box {
                position: absolute;
                top: 1em;
                right: 1em;
                background-color: rgba(255, 255, 255, 0.5);
                padding: 0.3em 0.5em;
                border-radius: 0.3em;
            }

            div.device-msg {
                position: absolute;
                top: 1em;
                left: 1em;
                color: #fff;
                font-size: 12px;
                box-shadow: 1px 1px 2px #000;
                opacity: 0.6;
            }

            div.disconnect-box {
                position: absolute;
                bottom: 10px;
                right: 1em;
            }

            div.ptz-ctl-box {
                position: absolute;
                width: 100px;
                height: 100px;
                bottom: 10px;
                left: calc(50% - 40px);
            }

            div.ptz-ctl-box div.ptz-pad-box {
                width: 100px;
                height: 100px;
                border-radius: 50px;
                background-color: #ffffff;
                color: #000000;
                position: absolute;
                opacity: 0.4;
            }

            div.ptz-ctl-box div.ptz-pad-box:hover {
                opacity: 0.6;
            }

            div.ptz-ctl-box button.ptz-goto-home {
                width: 25px;
                height: 25px;
                border-width: 0px;
                border-radius: 25px;
                position: absolute;
                top: 50%;
                left: 50%;
                -webkit-transform: translate(-50%, -50%);
                transform: translate(-50%, -50%);
                z-index: 1000;
            }

            div.ptz-ctl-box div.ptz-pad-box .left {
                position: absolute;
                left: 10px;
                top: 44px;
            }

            div.ptz-ctl-box div.ptz-pad-box .right {
                position: absolute;
                right: 10px;
                top: 44px;
            }

            div.ptz-ctl-box div.ptz-pad-box .up {
                position: absolute;
                left: 44px;
                top: 10px;
            }

            div.ptz-ctl-box div.ptz-pad-box .down {
                position: absolute;
                left: 44px;
                top: 76px;
            }

            div.disconnect-box button[name="disconnect"] {
                opacity: 0.5 !important;
            }

            div.disconnect-box button[name="disconnect"]:hover {
                opacity: 1 !important;
            }

            div.ptz-zom-ctl-box {
                position: absolute;
                bottom: 120px;
                right: 1em;
                opacity: 0.4;
            }

            div.ptz-zom-ctl-box:hover {
                opacity: 0.6;
            }

            // @media (max-width: 768px) {
            //     div.ptz-spd-ctl-box {
            //         display: none;
            //     }

            //     div.ptz-ctl-box {
            //         bottom: 10px;
            //     }
            // }
        }

        .connect-form,
        .connect-desc {
            width: 50%;
            margin: auto;
            background: #fff;
            padding: 30px;
            border-radius: 6px;
            box-shadow: 5px 3px 8px #00000020;
        }

        .connect-desc {
            text-align: center;
        }
    }

    ::v-deep {
        h1 {
            margin: 0;
        }

        .el-loading-text {
            text-shadow: 1px 1px 2px #000;
            color: #fff;
        }

        .el-icon-loading {
            color: #fff
        }
    }
}
</style>
